//给定一个数组 nums，编写一个函数将所有 0 移动到数组的末尾，同时保持非零元素的相对顺序。 
//
// 示例: 
//
// 输入: [0,1,0,3,12]
//输出: [1,3,12,0,0] 
//
// 说明: 
//
// 
// 必须在原数组上操作，不能拷贝额外的数组。 
// 尽量减少操作次数。 
// 
// Related Topics 数组 双指针 
// 👍 1293 👎 0

package com.cute.leetcode.editor.cn;
public class MoveZeroes {
    public static void main(String[] args) {
        Solution solution = new MoveZeroes().new Solution();
    }
    //leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    /**
     * 行吧，这个时间和空间占用我都服了，但是解决了问题
     * 从后向前遍历，如果发现0则将剩下的所有元素前移，然后末尾添0
     */
    public void moveZeroes(int[] nums) {
        int end = nums.length-1;
        for (int i = end; i >=0 ; i--) {
            if (nums[i] == 0 && i < end){
                for (int j = i; j < end ; j++) {
                    nums[j] = nums[j+1];
                }
                nums[end] = 0;
                end--;
            }
        }
    }

    /**
     * 题解中的方法1，取两个指针，i去遍历所有元素，j指向零的位置，如果i找到了非零元素，则移动到j的位置
     * j然后++，最后j指向的位置开始向后全给0就可以了
     */
    public void moveZeroes1(int[] nums) {
        int j = 0;
        for (int i = 0; i <nums.length ; i++) {
            if (nums[i]!=0) nums[j++] = nums[i];//j在赋值的时候要么指向i，要么指向为0的下标！！
        }
        for (int i = j; i <nums.length ; i++) {
            nums[i] =0;
        }
    }

    /**
     * 方法2，利用快速排序的思想，一次遍历，不为0就进行交换，相当于是把0当成了中间值
     * 这是优化过的方法，优化之前是只要不为0就进行交换，现在是只有在i>j时才会交换
     */
    public void moveZeroes2(int[] nums) {
        if (nums==null || nums.length == 0) return;
        int j = 0;
        for (int i = 0; i <nums.length ; i++) {
            if (nums[i]!=0){
                if (i>j){
                    nums[j] = nums[i];
                    nums[i] = 0;
                }
                j++;
            }
        }
    }
}
//leetcode submit region end(Prohibit modification and deletion)

}